
#include "toolsbom.h"

// 大小端转换
#if HOST_IS_BIGENDIAN
static void swapArchiveRecord (ARCHIVE_RECORD *rec)
{
    rec->date = SHORT_SWAP(rec->date);
    rec->time = SHORT_SWAP(rec->time);
    rec->outTemp = SHORT_SWAP(rec->outTemp);
    rec->highOutTemp = SHORT_SWAP(rec->highOutTemp);
    rec->lowOutTemp = SHORT_SWAP(rec->lowOutTemp);
    rec->rain = SHORT_SWAP(rec->rain);
    rec->highRainRate = SHORT_SWAP(rec->highRainRate);
    rec->barometer = SHORT_SWAP(rec->barometer);
    rec->radiation = SHORT_SWAP(rec->radiation);
    rec->windSamples = SHORT_SWAP(rec->windSamples);
    rec->inTemp = SHORT_SWAP(rec->inTemp);

    return;
}
#else
static void swapArchiveRecord (ARCHIVE_RECORD *rec)
{
    return;
}
#endif

// 完成将字串指令末尾加上davis协议特有的\x0a，并通过socket发出去
int sendcmd(int serverfd, char * cmd)
{
	int cmdlen = 0;
	int retcode;
	char str[MAXCMD];
	memset(str, '\0', MAXCMD);
	memcpy(str, cmd, strlen(cmd));
	str[strlen(cmd)] = '\x0a';
	cmdlen = strlen(cmd)+1;
	retcode = TCPWrite(serverfd, cmd, cmdlen);
	if (retcode < 0)
	{
		printf("main: send cmd [%s] failed [%d]\n", cmd, retcode);
		return -4;
	}
	printf("main: cmd [%s] sent\n", cmd);
	return cmdlen;
}

// 读len个字节的数据并校验crc
int readWithCRC (int serverfd, void *bfr, int len)
{
    int     retVal, index = 0;
    unsigned char   *ptr = (unsigned char *)bfr;
    unsigned short  crc = 0;

    //retVal = (*work->medium.read) (&work->medium, bfr, len, msTimeout);
    retVal = TCPBlockRead(serverfd, (char*)bfr, len);
    if (retVal != len)
    {
        return -1;
    }

    for (index = 0; index < len; index ++)
    {
        crc =  crc_table [(crc >> 8) ^ ptr[index]] ^ (crc << 8);
    }

    return (crc == 0) ? (len) : (-2);
}

// 对数据块生成crc
unsigned short genCRC (void *data, int length)
{
    unsigned char           *ptr = (unsigned char *)data;
    unsigned short          crc = 0;
    register int    i;

    for (i = 0; i < length; i ++)
    {
        crc =  crc_table[(crc >> 8) ^ ptr[i]] ^ (crc << 8);
    }

    crc = ((crc >> 8) & 0xFF) | ((crc << 8) & 0xFF00);
    return crc;
}

// 把二进制数据末尾加上crc校验码，并通过socket发出去
int writeWithCRC (int serverfd, void *buffer, int length)
{
    int     retVal;
    int     wrerrno = 0;
    unsigned short  crc;

    crc = SHORT_SWAP(genCRC (buffer, length));

    //retVal = (*work->medium.write) (&work->medium, buffer, length);
    retVal = TCPWrite(serverfd, buffer, length);
    if (retVal != length)
    {
        if (retVal == -1)
        {
            wrerrno = errno;
        }

        return -1;
    }
    //retVal = (*work->medium.write) (&work->medium, &crc, 2);
    retVal = TCPWrite(serverfd, (void *)&crc, 2);
    if (retVal != 2)
    {
        if (retVal == -1)
        {
            wrerrno = errno;
        }

        return -2;
    }

    /*  ... now wait for the TX buffer to empty out (this blocks)
    */
    //(*work->medium.txdrain) (&work->medium);

    return length;
}

// 唤醒console
int wakeup(int serverfd)
{
	char wake[10];
	memset(wake, '\0', 10);
	printf("wake up!\n");
	if (TCPWrite(serverfd, "\x0a", 1) < 0)
	{
		printf("main: tcp write failed!\n");
		return -2;
	}
	if (TCPBlockRead(serverfd, wake, 10)<0)
	{
		printf("main: tcp read failed!\n");
		return -3;
	}
	printf("Wakup! %s\n", wake);
	return 0;
}

// 取ack
int getack(int serverfd)
{
	char ack = 0;
	if (TCPBlockRead(serverfd, &ack, 1) < 0)
	{
		printf("main: receive data failed\n");
		return -1;
	}
	printf("read [%x]\n", (int)ack);
	if (ack != 0x06)	//ack
	{
		printf("cmd not recognized \n");
		return -2;
	}
	return 0;
}

// * Calculated Weather Data
//  calculate the heat index
float wvutilsCalculateHeatIndex (float temp, float humidity)
{
    double      T1, T2, T3, T4, T5, T6, T7, T8, T9, result;

    if (temp < 75.0)
    {
        return temp;
    }

    T1 = -42.379;
    T2 = 2.04901523 * temp;
    T3 = 10.14333127 * humidity;
    T4 = -0.22475541 * temp * humidity;
    T5 = -6.83783E-3 * (temp * temp);
    T6 = -5.481717E-2 * (humidity * humidity);
    T7 = 1.22874E-3 * (temp * temp) * humidity;
    T8 = 8.5282E-4 * temp * (humidity * humidity);
    T9 = -1.99E-6 * (temp * temp) * (humidity * humidity);
    result = T1 + T2 + T3 + T4 + T5 + T6 + T7 + T8 + T9;

    return (float)result;
}

//  calculate the wind chill
float wvutilsCalculateWindChill (float temp, float windspeed)
{
    double      T1, T2, T3, T4;
    double      result;

    if (temp >= 50.0 || windspeed <= 3.0)
    {
        return temp;
    }

    T1 = 35.74;
    T2 = 0.6215 * temp;
    T3 = -1.0 * (35.75 * pow (windspeed, 0.16));
    T4 = 0.4275 * temp * pow (windspeed, 0.16);
    result = T1 + T2 + T3 + T4;

    return (float)result;
}

//  calculate the dewpoint
float wvutilsCalculateDewpoint (float temp, float humidity)
{
    float       Tc  = (5.0/9.0)*(temp - 32.0);
    float       Es  = 6.11 * pow ((double)10.0, (double)(7.5 * (Tc/(237.7 + Tc))));
    float       E   = (humidity * Es)/100;
    float       Tdc = (-430.22 + 237.7 * log(E))/(-log(E)+19.08);
    return ((9.0/5.0) * Tdc + 32);
}

// write block to file
int blockwritefile(char * filename, void * blockpoint, int blocklength)
{
	FILE * filepoint;
	int length;
	
	filepoint = fopen(filename, "wb");
	
	length = fwrite(blockpoint, sizeof(char), blocklength, filepoint);
	if (length != blocklength)
	{
		printf("file write error\n");
		return -2;
	}
	
	fclose(filepoint);
	return length;
}

// read from file to block
int blockreadfile(char * filename, void * blockpoint, int blocklength)
{
	FILE * filepoint;
	int length;
	filepoint = fopen(filename, "rb");
	if (filepoint == NULL)
	{
		printf("%s does not exist!\n", filename);
		return -1;
	}
	
	fseek(filepoint, 0, SEEK_END);
	if (blocklength != ftell(filepoint))
	{
		printf("file size error!\n");
		return -2;
	}
	
	fseek(filepoint, 0, SEEK_SET);
	length = fread(blockpoint, sizeof(char), blocklength, filepoint);
	if (length != blocklength)
	{
		printf("file write error\n");
		return -3;
	}
	
	fclose(filepoint);
	return length;
}


